# ifndef __MathAlgo_H_
# define __MathAlgo_H_

	// _pK [0 ... _cN + 1]
float Polynom (size_t _cN, const float * _pK, float _x);

struct point_t;

	// Solve system of 3 linear equations:  B + Ax*x[i] + Ay*y[i] = screen[i]
	// to get values of B, Ax and Ay from known (x,y)->screen.
bool Solve3x3 (const point_t _points [3], const float _lScreen [3], float & _Ax, float & _Ay, float & _B);

	// Solve system of 4 linear equations:  B + Ax*x[i] + Ay*y[i] + D*x[i]*y[i] = screen[i]
	// to get values of B, Ax and Ay, D from known (x,y)->screen.
bool Solve4x4_XY (const point_t _points [4], const float _lScreen [4], float & _Ax, float & _Ay, float & _B, float & _D);

	// Solve system of 4 linear equations:  B + Ax*x[i] + Ay*y[i] + D*x[i]*x[i] = screen[i]
	// to get values of B, Ax and Ay, D from known (x,y)->screen.
bool Solve4x4_XX (const point_t _points [4], const float _lScreen [4], float & _Ax, float & _Ay, float & _B, float & _D);

    //
    // Helper class implementing Gauss' method.
    //
class CLinearEquationSystem {
	// Disable copy semantics.
	CLinearEquationSystem (const CLinearEquationSystem &);
	void operator = (const CLinearEquationSystem &);
  public:
    CLinearEquationSystem (size_t _N);
    ~CLinearEquationSystem ();

    double   Matrix (size_t _i, size_t _j) const {assert (_i < N && _j < N); return m_pMatrix [_j].pCells [_i];}
    double & Matrix (size_t _i, size_t _j)       {assert (_i < N && _j < N); return m_pMatrix [_j].pCells [_i];}

    double   FreeVector (size_t _j) const {assert (_j < N); return m_pMatrix [_j].fFreeCell;}
    double & FreeVector (size_t _j)       {assert (_j < N); return m_pMatrix [_j].fFreeCell;}

    // Fill the matrix and the free vector by zeros.
    void SetZero ();

    // Implement Gauss' method.
    // Call of the function destroys data in the matrix and in the free vector
    // and constructs data for Solution().
    // Return true on error. You may call GetErrorIndex() to determine index of
    // the equation linearly dependent from equations located above it in the system.
    bool Solve (double _fMinValue = 1e-20);
    // Solutions are in the free vector.
    double Solution (size_t _i) const {return FreeVector (_i);}
    // Return index of first encountered degenerating equation.
    size_t GetErrorIndex () const {return m_cErrorIndex;}

	// The dimension of the system.
    size_t const N;

  private:
    struct CString {
        double * pCells;
        double   fFreeCell;
        size_t   cIndex;
    };
    CString * const m_pMatrix;

    size_t m_cErrorIndex;
    void SwapStrings (size_t _j1, size_t _j2);
};

# endif // __MathAlgo_H_